<?php

/**
 * Base class for all Controllers
 *
 * @since 1.0
 */
class Controller {

    /**
     * The Controller database reference
     * @var Database
     */
    private $db = NULL;
    
    /**
     * A list of Models to be used by this controller
     * @var array
     */
    protected $models = array();
    
    /**
     * A reference to the View to render this controller content with
     * 
     * @var View
     */
    protected $view = NULL;
    
    /**
     * The name of the template file to render with
     * 
     * @var string
     */
    protected $template = "index.php";
	
	/**
	 * Enables controller based actions to render automatically, or to turn off
	 * automatic rendering of action views
	 */
	public $variables = array();
	
    /**
     * A list of Helper class references to use within this controller
     * 
     * @var array
     */
	protected $helpers = array('HTML','Request');
	
	/**
	 * Enables controller based actions to render automatically, or to turn off
	 * automatic rendering of action views
	 */
	public $autoRender = true;
	
	/**
	 * Enables controller based actions to render their layout automatically, or to turn off
	 * automatic layout rendering of action views
	 */
	public $autoLayout = true;

    /**
     * The Controller constructor
     */
    public function __construct() {
        $this->db = new Database();
		
		// initiate the helper classes available for use by this Controller
		if( $this->helpers != NULL ) {
            foreach($this->helpers as $helper) {
                if( class_exists($helper) && is_subclass_of($helper, 'Helper') ) {
                    $this->{$helper} = new $helper($this);
                }
            }
        }
        
        // initiate the models as class variables
        if( $this->models != NULL ) {
            foreach($this->models as $model) {
                if( class_exists($model) ) {
                    $this->{$model} = new $model();
                }
            }
        }
        
        // initiate the view instance
        if( $this->view == NULL ) {
            $this->view = new View($this, $this->template);
        }
    }

    /**
     * Returns the database object used by the Controller
     *
     * @return Database
     */
    public function getDatabase() {
        if ($this->db == NULL) {
            $this->db = new Database();
        }

        return $this->db;
    }

    /**
     * Replaces the current database object with a new one
     *
     * @param Database $db
     */
    public function setDatabase($db) {
        $this->db = $db;
    }

    /**
     * Returns the value of the database result array
     *
     * @param Array $data Result Array returned from the Database::getResult() call
     * @param String $key the key for the field column
     */
    public function getValue($data, $key, $index) {
        return ( isset($data[$index]) ) ? $data[$index][$key] : $data[$key];
    }

    /**
     * Returns the size of the result array returned from the Database::getResult()
     * call
     *
     * @param Array $data the database array returned from the Database::getResult() call
     */
    public function getResultCount($data) {
        return ( isset($data[0]) ) ? count($data) :
            ( count(array_keys($data)) > 0 ? 1 : 0 );
    }

    

    /**
     * Employs the find operations of the specified class and returns the necessary
     * results
     *
     * @param $className the name of the Model Instance to use to search
     * @param $options the search parameters
     */
    public function find($className, $options = NULL) {
        if( !$this->isValidClassName($className) ) {
            return NULL;
        }

        $class = new $className();

        return $class->find($options);
    }
	
    /**
     * Returns the total number of $className records in the database based
     * on the supplied options
     * 
     * @param string $className
     * @param array $options
     * @return Model 
     */
	public function count($className, $options = NULL) {
		if( !$this->isValidClassName($className) ) {
            trigger_error("Invalid Class Name for Controller Item: " . $className);
            return NULL;
        }

        $class = new $className();

        return $class->count($options);
	}

    /**
     * Returns true if
     *  - $className IS NOT NULL and
     *  - $className is an actual class and
     *  - $className represents a class which is a Model Class instance
     * 
     * @param string $className
     * @return bool
     */
    public function isValidClassName($className) {
        if ($className == NULL) {
            trigger_error("No Class Name has been speficied for the Items/Categories of this Controller");
            return false;
        }

        if (!class_exists($className)) {
            trigger_error($className . " is not a valid PHP Class ");
            return false;
        }

        if (!(new $className() instanceof Model)) {
            trigger_error($className . " has to be an instance of Model ");
            return false;
        }

        return true;
    }
    
    /**
     * Passes a variable or set of variables to the view for rendering
     * 
     * @param mixed $key
     * @param mixed $value 
     */
    public function set($key, $variable = NULL) {
		
		if (is_null($key)) {
            throw new InvalidArgumentException("A valid variable or array must be passed");
        }

        // consider the case where an array of variables can be passed instead
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                $this->variables[$k] = $v;
            }
        }

        if (is_string($key) && !is_null($variable)) {
            $this->variables[$key] = $variable;
        }
		
		if( $this->view != NULL ) {
            $this->view->set($key, $variable);
        }
    }

    /**
     * Renders the contents of the Controller to the view
     */
    public function render() {
        
        if( $this->view != NULL ) {
            $this->view->render();
        }
    }
}

?>
